package org.amn.concurrent;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.log4j.Logger;
import org.springframework.util.Assert;

/**
 * <p>
 * 描述:阻塞索引队列
 * </p>
 *
 * @see
 * @author yangjun1120@gmail.com
 *
 */
public class IndexBlockingQueue<E> implements IindexQueue<E> {

    private static Logger logger = Logger.getLogger(IndexBlockingQueue.class);

    private LinkedBlockingQueue<E> q;
    private int capacity;
    private AtomicInteger count = new AtomicInteger(0);

    public IndexBlockingQueue(int aCapacity) {
        q = new LinkedBlockingQueue<E>(aCapacity);
        this.capacity = aCapacity;

    }

    @Override
    public void clear() {
        q.clear();
        count.set(0);
    }

    @Override
    public boolean offer(E e) {
        Assert.notNull(e, "object must be null!");

        boolean f = false;

        if (count.get() >= capacity) {
            return false;
        }

        try {
            f = q.offer(e, 5L, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e1) {
            logger.warn("thread is interrupted", e1);
            f = false;
        } finally {
            if (f) {
                count.incrementAndGet();
            }
        }

        return f;
    }

    @Override
    public E poll() {

        E e = null;
        try {
            e = q.poll(5L, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e1) {
            e = null;
        }

        if (e != null) {
            count.decrementAndGet();
        }

        return e;
    }

    @Override
    public E peek() {
        return q.peek();
    }

    @Override
    public int size() {
        return q.size();
    }

    @Override
    public boolean isEmpty() {
        return q.isEmpty();
    }

    @Override
    public int capacity() {
        return this.capacity;
    }

    public static void main(String[] args) throws Exception {
        LinkedBlockingQueue<String> q = new LinkedBlockingQueue<String>(1);
        q.offer("1");
        q.offer("2");
        System.out.println("ok!");
    }
}
